﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Xml;
using System.IO;
using System.Reflection;

namespace FourSquareNETCFLibrary
{
    public class FourSquare
    {
        private string USER_AGENT;
        private string _Username;
        private string _Password;
        private NetworkCredential c;

        /// <summary>
        /// Creates a new instance of the FourSquare library
        /// </summary>
        /// <param name="Username">FourSquare username</param>
        /// <param name="Password">FourSquare password</param>
        public FourSquare(string Username, string Password)
        {
            this._Username = Username;
            this._Password = Password;
            this.c = new NetworkCredential(this._Username, this._Password);

            //set the USER_AGENT based on the calling program:
            string AppTitle= ((AssemblyTitleAttribute)Attribute.GetCustomAttribute(Assembly.GetCallingAssembly(), typeof(AssemblyTitleAttribute))).Title;
            string AppVersion = Assembly.GetCallingAssembly().GetName().Version.ToString();
            string ClassTitle = ((AssemblyTitleAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(AssemblyTitleAttribute))).Title;
            string ClassVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
            this.USER_AGENT = AppTitle + ":" + AppVersion + " (" + ClassTitle + ":" + ClassVersion + ")";
        }

        /// <summary>
        /// Private method to get data from a URL using authentication
        /// </summary>
        /// <param name="Url">URL to fetch</param>
        /// <returns>the XML response</returns>
        private XmlDocument GetData(Uri Url)
        {
            HttpWebRequest r = (HttpWebRequest)HttpWebRequest.Create(Url);
            r.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(this._Username + ":" + this._Password)));
            r.Method = "GET";
            r.UserAgent = USER_AGENT;
            using (WebResponse wr = r.GetResponse())
            {
                using (Stream s = wr.GetResponseStream())
                {
                    XmlDocument d = new XmlDocument();
                    d.Load(wr.GetResponseStream());
                    return d;
                }
            }
        }

        /// <summary>
        /// Private method to get data from a URL with parameters using authentication
        /// </summary>
        /// <param name="Url">URL to fetch</param>
        /// <param name="Data">A dictionary object of parameters (keys) and values of the data to send.</param>
        /// <returns>the XML response</returns>
        private XmlDocument GetData(Uri Url, Dictionary<string, string> Data)
        {
            HttpWebRequest r = (HttpWebRequest)HttpWebRequest.Create(Url);
            r.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(this._Username + ":" + this._Password)));
            r.Method = "GET";
            r.UserAgent = USER_AGENT;
            string content = "?";
            foreach (string k in Data.Keys)
            {
                content = k + "=" + Data[k] + "&";
            }
            content = content.TrimEnd(new char[] { '&' });
            using (WebResponse wr = r.GetResponse())
            {
                using (Stream s = wr.GetResponseStream())
                {
                    XmlDocument d = new XmlDocument();
                    d.Load(wr.GetResponseStream());
                    return d;
                }
            }
        }

        /// <summary>
        /// Private method to post data to a URL using authentication
        /// </summary>
        /// <param name="Url">URL to fetch</param>
        /// <param name="Data">A dictionary object of parameters and values of the data to send.</param>
        /// <returns>the XML response</returns>
        private XmlDocument PostData(Uri Url, Dictionary<string, string> Data)
        {
            HttpWebRequest r = (HttpWebRequest)HttpWebRequest.Create(Url);
            r.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(this._Username + ":" + this._Password)));
            r.UserAgent = USER_AGENT;
            r.Method = "POST";
            r.ContentType = "application/x-www-form-urlencoded";
            string content = "?";
            foreach (string k in Data.Keys)
            {
                content = k + "=" + Data[k] + "&";
            }
            content = content.TrimEnd(new char[] { '&' });
            ASCIIEncoding encoding = new ASCIIEncoding();
            byte[] byte1 = encoding.GetBytes(content);
            r.ContentLength = byte1.Length;
            using (Stream rs = r.GetRequestStream())
            {
                rs.Write(byte1, 0, byte1.Length);
                rs.Close();
                using (WebResponse wr = r.GetResponse())
                {
                    using (Stream s = wr.GetResponseStream())
                    {
                        XmlDocument d = new XmlDocument();
                        d.Load(s);
                        return d;
                    }
                }
            }
        }


        #region Check in methods
        /// <summary>
        /// Returns a list of recent checkins from friends
        /// </summary>
        /// <returns>List of checkin objects</returns>
        public List<checkin> GetCheckins()
        {
            List<checkin> checkins = new List<checkin>();
            XmlDocument d = GetData(new Uri("http://api.foursquare.com/v1/checkins"));
            XmlNodeList nlist = d.SelectNodes("/checkins/checkin");
            foreach (XmlNode n in nlist)
            {
                checkins.Add(new checkin(n));
            }
            return checkins;
        }

        /// <summary>
        /// Returns a list of recent checkins from friends based on location
        /// </summary>
        /// <param name="Latitude">Latitude</param>
        /// <param name="Longitude">Longitude</param>
        /// <returns>List of checkin objects</returns>
        public List<checkin> GetCheckins(double Latitude, double Longitude)
        {
            List<checkin> checkins = new List<checkin>();
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("geolat", Latitude.ToString());
            Params.Add("geolong", Longitude.ToString());
            XmlDocument d = GetData(new Uri("http://api.foursquare.com/v1/checkins?geolat="),Params);
            XmlNodeList nlist = d.SelectNodes("/checkins/checkin");
            foreach (XmlNode n in nlist)
            {
                checkins.Add(new checkin(n));
            }
            return checkins;
        }

        /// <summary>
        /// Allows you to check-in to a place
        /// </summary>
        /// <param name="Vid">(optional, not necessary if you are 'shouting' or have a venue name). ID of the venue where you want to check-in</param>
        /// <param name="Venue">(optional, not necessary if you are 'shouting' or have a vid) if you don't have a venue ID or would rather prefer a 'venueless' checkin, pass the venue name as a string using this parameter. it will become an 'orphan' (no address or venueid but with geolat, geolong)</param>
        /// <param name="Shout">(optional) a message about your check-in. the maximum length of this field is 140 characters</param>
        /// <param name="Private">(optional). "1" means "don't show your friends". "0" means "show everyone"</param>
        /// <param name="Twitter">(optional, defaults to the user's setting). "1" means "send to Twitter". "0" means "don't send to Twitter"</param>
        /// <param name="Facebook">(optional, defaults to the user's setting). "1" means "send to Facebook". "0" means "don't send to Facebook"</param>
        /// <param name="Latitude">(optional, but recommended)</param>
        /// <param name="Longitude">(optional, but recommended)</param>
        /// <returns>chekin Object </returns>
        public checkin CheckinTo(string Vid, string Venue, string Shout, bool? Private, bool? Twitter, bool? Facebook, double? Latitude, double? Longitude)
        {
            Dictionary<string, string> parameters = new Dictionary<string, string>();
            if (Vid != null)
            {
                parameters.Add("vid", Vid);
            }
            if (Venue != null)
            {
                parameters.Add("venue", Venue);
            }
            if (Private.HasValue)
            {
                if (Private.Value)
                {
                    parameters.Add("private", "1");
                }
                else
                {
                    parameters.Add("private", "0");
                }
            }
            if (Shout != null)
            {
                parameters.Add("shout", Shout);
            }
            if (Twitter.HasValue)
            {
                if (Twitter.Value)
                {
                    parameters.Add("twitter", "1");
                }
                else
                {
                    parameters.Add("twitter", "0");
                }
            }
            if (Facebook.HasValue)
            {
                if (Facebook.Value)
                {
                    parameters.Add("facebook", "1");
                }
                else
                {
                    parameters.Add("facebook", "0");
                }
            }
            if (Latitude.HasValue && Longitude.HasValue)
            {
                parameters.Add("geolat", Latitude.Value.ToString());
                parameters.Add("geolong", Longitude.Value.ToString());
            }
            XmlDocument d = PostData(new Uri("http://api.foursquare.com/v1/checkin"), parameters);
            return new checkin(d.SelectSingleNode("/checkin"));
        }

        /// <summary>
        /// Returns a history of checkins for the authenticated user.
        /// </summary>
        /// <returns>A list of checkin objects</returns>
        public List<checkin> GetHistory()
        {
            List<checkin> checkins = new List<checkin>();
            XmlDocument d = GetData(new Uri("http://api.foursquare.com/v1/history"));
            XmlNodeList nlist = d.SelectNodes("/checkins/checkin");
            foreach (XmlNode n in nlist)
            {
                checkins.Add(new checkin(n));
            }
            return checkins;
        }

        /// <summary>
        /// Returns a history of checkins for the authenticated user.
        /// </summary>
        /// <param name="Limit">number of checkins to return</param>
        /// <param name="StartId">id to start returning results from (optional, if null, returns most recent results)</param>
        /// <returns>A list of checkin objects</returns>
        public List<checkin> GetHistory(int Limit, string StartId)
        {
            List<checkin> checkins = new List<checkin>();
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("l", Limit.ToString());
            if (StartId != null)
            {
                Params.Add("sinceid", StartId);
            }
            XmlDocument d = GetData(new Uri("http://api.foursquare.com/v1/history"),Params);
            XmlNodeList nlist = d.SelectNodes("/checkins/checkin");
            foreach (XmlNode n in nlist)
            {
                checkins.Add(new checkin(n));
            }
            return checkins;
        }

        #endregion

        #region User methods

        /// <summary>
        /// Returns profile information for a user
        /// </summary>
        /// <param name="Uid">UserID of the user to get information for</param>
        /// <param name="Badges">(optional, default: false) set to true ("1") to also show badges for this user. by default, this will only show badges from the authenticated user's current city.</param>
        /// <param name="Mayor">(optional, default: false) set to true ("1") to also show venues for which this user is a mayor. by default, this will show mayorships worldwide.</param>
        /// <returns>a user object</returns>
        public user GetUser(string Uid, bool? Badges, bool? Mayor)
        {
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("uid", Uid);
            if (Badges.HasValue)
            {
                Params.Add("badges", Convert.ToInt32(Badges.Value).ToString());
            }
            if (Mayor.HasValue)
            {
                Params.Add("mayor", Convert.ToInt32(Mayor.Value).ToString());
            }    
            XmlDocument d = GetData(new Uri("http://api.foursquare.com/v1/user"),Params);
            return new user(d.SelectSingleNode("/user"));
        }

        /// <summary>
        /// Returns a list of friends
        /// </summary>
        /// <returns>a List of user objects</returns>
        public List<user> Friends()
        {
            List<user> u = new List<user>();
            XmlDocument d = GetData(new Uri("http://api.foursquare.com/v1/friends"));
            XmlNodeList nlist = d.SelectNodes("/friends/user");
            foreach (XmlNode n in nlist)
            {
                u.Add(new user(n));
            }
            return u;
        }

        /// <summary>
        /// Returns a list of friends
        /// </summary>
        /// <param name="Uid">user id of the person for whom you want to pull a friend graph</param>
        /// <returns>a List of user objects</returns>
        public List<user> Friends(string Uid)
        {
            List<user> u = new List<user>();
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("uid", Uid);
            XmlDocument d = GetData(new Uri("http://api.foursquare.com/v1/friends"),Params);
            XmlNodeList nlist = d.SelectNodes("/friends/user");
            foreach (XmlNode n in nlist)
            {
                u.Add(new user(n));
            }
            return u;
        }
        #endregion

        #region Venue methods

        /// <summary>
        /// Returns a list of venues near the area specified, or that matches the search term.
        /// </summary>
        /// <param name="Latitude">latitude</param>
        /// <param name="Longitude">longitude</param>
        /// <param name="Limit">limit of results (optional, default 10)</param>
        /// <param name="Query">(optional) keyword search</param>
        /// <returns></returns>
        public List<venue> SearchVenues(double Latitude, double Longitude, int? Limit, string Query)
        {
            List<venue> venues = new List<venue>();
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("geolat", Latitude.ToString());
            Params.Add("geolong", Longitude.ToString());
            if (Limit.HasValue)
            {
                Params.Add("l", Limit.Value.ToString());
            }
            if (Query != null)
            {
                Params.Add("q", Query);
            }
            //XmlDocument d = GetData(new Uri("http://api.foursquare.com/v1/venues?geolat=38.895111&geolong=-77.036667&q=" + q));
            XmlDocument d = GetData(new Uri("http://api.foursquare.com/v1/venues"),Params);
            XmlNodeList nlist = d.SelectNodes("/venues/group/venue");
            foreach (XmlNode n in nlist)
            {
                venues.Add(new venue(n));
            }
            return venues;
        }

        /// <summary>
        /// Returns details about a venue
        /// </summary>
        /// <param name="Vid">the ID for the venue for which you want information</param>
        /// <returns>a venue object</returns>
        public venue VenueDetails(string Vid)
        {
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("vid", Vid);
            XmlDocument d = GetData(new Uri("http://api.foursquare.com/v1/venue"), Params);
            return new venue(d.SelectSingleNode("/venue"));
        }

        /// <summary>
        /// Adds a new venue
        /// </summary>
        /// <param name="Name">the name of the venue</param>
        /// <param name="Address">the address of the venue</param>
        /// <param name="Crossstreet">the cross streets</param>
        /// <param name="City">the city name where this venue is</param>
        /// <param name="State">the state where the city is</param>
        /// <param name="ZipCode">(optional) the ZIP code for the venue</param>
        /// <param name="PhoneNumber">(optional) the phone number for the venue</param>
        /// <param name="Latitude">(optional, but recommended)</param>
        /// <param name="Longitude">(optional, but recommended)</param>
        /// <returns>the new venue object</returns>
        public venue AddVenue(string Name, string Address, string Crossstreet, string City, string State, string ZipCode, string PhoneNumber, double? Latitude, double? Longitude)
        {
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("name", Name);
            Params.Add("address", Address);
            Params.Add("crossstreet", Crossstreet);
            Params.Add("city", City);
            Params.Add("state", State);
            if (ZipCode != null)
            {
                Params.Add("zip", ZipCode);
            }
            if (PhoneNumber != null)
            {
                Params.Add("phone", PhoneNumber);
            }
            if (Latitude.HasValue && Longitude.HasValue)
            {
                Params.Add("geolat", Latitude.ToString());
                Params.Add("geolong", Longitude.ToString());
            }
            XmlDocument d = PostData(new Uri("http://api.foursquare.com/v1/addvenue"), Params);
            return new venue(d.SelectSingleNode("/venue"));
        }

        /// <summary>
        /// Allows you to flag/propose a change to a venue.
        /// </summary>
        /// <param name="Name">the name of the venue</param>
        /// <param name="Address">the address of the venue</param>
        /// <param name="Crossstreet">the cross streets</param>
        /// <param name="City">the city name where this venue is</param>
        /// <param name="State">the state where the city is</param>
        /// <param name="ZipCode">(optional) the ZIP code for the venue</param>
        /// <param name="PhoneNumber">(optional) the phone number for the venue</param>
        /// <param name="Latitude">(optional, but recommended)</param>
        /// <param name="Longitude">(optional, but recommended)</param>
        /// <returns>the new venue object</returns>
        public venue EditVenue(string Name, string Address, string Crossstreet, string City, string State, string ZipCode, string PhoneNumber, double? Latitude, double? Longitude)
        {
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("name", Name);
            Params.Add("address", Address);
            Params.Add("crossstreet", Crossstreet);
            Params.Add("city", City);
            Params.Add("state", State);
            if (ZipCode != null)
            {
                Params.Add("zip", ZipCode);
            }
            if (PhoneNumber != null)
            {
                Params.Add("phone", PhoneNumber);
            }
            if (Latitude.HasValue && Longitude.HasValue)
            {
                Params.Add("geolat", Latitude.ToString());
                Params.Add("geolong", Longitude.ToString());
            }
            XmlDocument d = PostData(new Uri("http://api.foursquare.com/v1/venue/proposeedit"), Params);
            return new venue(d.SelectSingleNode("/venue"));
        }

        /// <summary>
        /// Flags a venue as closed
        /// </summary>
        /// <param name="Vid">the venue that you want marked closed</param>
        /// <returns>The result of the flag (ok)</returns>
        public string FlagVenueClosed(string Vid)
        {
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("vid", Vid);
            XmlDocument d = PostData(new Uri("http://api.foursquare.com/v1/venue/flagclosed"), Params);
            return d.SelectSingleNode("/response").InnerText;
        }

        #endregion

        #region Tip methods

        /// <summary>
        /// Returns a list of tips nearby
        /// </summary>
        /// <param name="Latitude">Latitude</param>
        /// <param name="Longitude">Longitude</param>
        /// <param name="Limit">limit of results (optional, default 30)</param>
        /// <returns>a list of tip objects</returns>
        public List<tip> GetTips(double Latitude, double Longitude, int? Limit)
        {
            List<tip> tips = new List<tip>();
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("geolat", Latitude.ToString());
            Params.Add("geolong", Longitude.ToString());
            if (Limit.HasValue)
            {
                Params.Add("l", Limit.Value.ToString());
            }
            XmlDocument d = GetData(new Uri("http://api.foursquare.com/v1/tips"),Params);
            XmlNodeList nlist = d.SelectNodes("/tips/group/tip");
            foreach (XmlNode n in nlist)
            {
                tips.Add(new tip(n));
            }
            return tips;
        }


        /// <summary>
        /// Adds a tip or a todo
        /// </summary>
        /// <param name="Vid">the venue where you want to add this tip</param>
        /// <param name="Text">the text of the tip or to-do item</param>
        /// <param name="Type">specify one of 'tip' or 'todo' (optional, default: tip)</param>
        /// <param name="Latitude">(optional) Latitude</param>
        /// <param name="Longitude">(optional) Longitude</param>
        /// <returns></returns>
        public tip AddTip(string Vid, string Text, string Type, double? Latitude, double? Longitude)
        {
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("vid", Vid);
            Params.Add("text", Text);
            if (Type != null)
            {
                Params.Add("type", Type);
            }
            if (Latitude.HasValue && Longitude.HasValue)
            {
                Params.Add("geolat", Latitude.ToString());
                Params.Add("geolong", Longitude.ToString());
            }
            XmlDocument d = PostData(new Uri("http://api.foursquare.com/v1/addtip"), Params);
            return new tip(d.SelectSingleNode("/tip"));
        }

        /// <summary>
        /// Marks a tip as a to-do item
        /// </summary>
        /// <param name="Tid">the tip that you want to mark to-do</param>
        /// <returns>the tip object of the tip marked as to-do</returns>
        public tip MarkTipAsToDo(string Tid)
        {
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("tid", Tid);
            XmlDocument d = PostData(new Uri("http://api.foursquare.com/v1/tip/marktodo"), Params);
            return new tip(d.SelectSingleNode("/tip"));
        }

        /// <summary>
        /// Marks a tip as done
        /// </summary>
        /// <param name="Tid">the tip that you want to mark done</param>
        /// <returns>the tip object of the tip marked as done</returns>
        public tip MarkTipAsDone(string Tid)
        {
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("tid", Tid);
            XmlDocument d = PostData(new Uri("http://api.foursquare.com/v1/tip/markdone"), Params);
            return new tip(d.SelectSingleNode("/tip"));
        }

        #endregion

        #region Friend methods
        /// <summary>
        /// Retreives pending friend requests
        /// </summary>
        /// <returns>a list of user objects</returns>
        public List<user> GetFriendRequests()
        {
            List<user> requests = new List<user>();
            XmlDocument d = GetData(new Uri("http://api.foursquare.com/v1/friend/requests"));
            XmlNodeList nlist = d.SelectNodes("/requests/user");
            foreach (XmlNode n in nlist)
            {
                requests.Add(new user(n));
            }
            return requests;
        }

        /// <summary>
        /// Approve a friend request
        /// </summary>
        /// <param name="Uid">UserID of the user to approve</param>
        /// <returns>a user object</returns>
        public user ApproveFriend(string Uid)
        {
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("uid", Uid);
            XmlDocument d = GetData(new Uri("http://api.foursquare.com/v1/friend/approve"), Params);
            return new user(d.SelectSingleNode("/user"));
        }

        /// <summary>
        /// Deny a friend request
        /// </summary>
        /// <param name="Uid">UserID of the user to deny</param>
        /// <returns>a user object</returns>
        public user DenyFriend(string Uid)
        {
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("uid", Uid);
            XmlDocument d = GetData(new Uri("http://api.foursquare.com/v1/friend/deny"), Params);
            return new user(d.SelectSingleNode("/user"));
        }

        /// <summary>
        /// Send a friend request
        /// </summary>
        /// <param name="Uid">UserID of the user to request</param>
        /// <returns>a user object</returns>
        public user RequestFriend(string Uid)
        {
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("uid", Uid);
            XmlDocument d = GetData(new Uri("http://api.foursquare.com/v1/friend/sendrequest"), Params);
            return new user(d.SelectSingleNode("/user"));
        }

        /// <summary>
        /// Find friends by name
        /// </summary>
        /// <param name="Query">String to search for</param>
        /// <returns>list of user objects</returns>
        public List<user> SearchUsers(string Query)
        {
            List<user> users = new List<user>();
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("q", Query);
            XmlDocument d = GetData(new Uri("http://api.foursquare.com/v1/findfriends/byname"),Params);
            XmlNodeList nlist = d.SelectNodes("/users/user");
            foreach (XmlNode n in nlist)
            {
                users.Add(new user(n));
            }
            return users;
        }

        /// <summary>
        /// Find friends by phone
        /// </summary>
        /// <param name="Query">String to search for</param>
        /// <returns>list of user objects</returns>
        public List<user> SearchUsersByPhone(string Query)
        {
            List<user> users = new List<user>();
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("q", Query);
            XmlDocument d = GetData(new Uri("http://api.foursquare.com/v1/findfriends/byphone"), Params);
            XmlNodeList nlist = d.SelectNodes("/users/user");
            foreach (XmlNode n in nlist)
            {
                users.Add(new user(n));
            }
            return users;
        }

        /// <summary>
        /// Find friends by twitter name
        /// </summary>
        /// <param name="Query">String to search for</param>
        /// <returns>list of user objects</returns>
        public List<user> SearchUsersByTwitter(string Query)
        {
            List<user> users = new List<user>();
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("q", Query);
            XmlDocument d = GetData(new Uri("http://api.foursquare.com/v1/findfriends/bytwitter"), Params);
            XmlNodeList nlist = d.SelectNodes("/users/user");
            foreach (XmlNode n in nlist)
            {
                users.Add(new user(n));
            }
            return users;
        }

        #endregion
        
        #region Settings methods

        /// <summary>
        /// Set pings for a user
        /// </summary>
        /// <param name="Uid">User if of the user to set pings for</param>
        /// <param name="OnOff"></param>
        /// <returns>Ping status</returns>
        public string SetPings(string Uid, bool OnOff)
        {
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add(Uid, Convert.ToInt32(OnOff).ToString());
            XmlDocument d = PostData(new Uri("http://api.foursquare.com/v1/settings/setpings"), Params);
            return d.SelectSingleNode("/settings/pings").InnerText;
        }

        /// <summary>
        /// Set pings for yourself
        /// </summary>
        /// <param name="OnOffGoodnight">Values are "on", "off", and "goodnight"</param>
        /// <returns>Ping status</returns>
        public string SetSelfPings(string OnOffGoodnight)
        {
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("self", OnOffGoodnight);
            XmlDocument d = PostData(new Uri("http://api.foursquare.com/v1/settings/setpings"), Params);
            return d.SelectSingleNode("/settings/pings").InnerText;
        }

        #endregion
    }
}
